package com.ruoyi.ldzlsb.service.impl;

import java.util.List;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Calendar;

import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.security.utils.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.ldzlsb.mapper.SbInspectionPlanMapper;
import com.ruoyi.ldzlsb.domain.SbInspectionPlan;
import com.ruoyi.ldzlsb.service.ISbInspectionPlanService;
import com.ruoyi.ldzlsb.service.ISbInspectionRecordService;
import com.ruoyi.ldzlsb.service.ISbInspectionConfigService;
import com.ruoyi.ldzlsb.domain.SbInspectionRecord;
import com.ruoyi.ldzlsb.domain.SbInspectionConfig;
import com.ruoyi.ldzlsb.mapper.SbEquipmentTypeMapper;

/**
 * 巡检计划Service业务层处理
 * 
 * @author anli
 * @date 2025-01-11
 */
@Service
public class SbInspectionPlanServiceImpl implements ISbInspectionPlanService 
{
    private static final Logger logger = LoggerFactory.getLogger(SbInspectionPlanServiceImpl.class);
    
    @Autowired
    private SbInspectionPlanMapper sbInspectionPlanMapper;

    @Autowired
    private ISbInspectionRecordService sbInspectionRecordService;
    
    @Autowired
    private ISbInspectionConfigService sbInspectionConfigService;
    
    @Autowired
    private SbEquipmentTypeMapper sbEquipmentTypeMapper;

    /**
     * 查询巡检计划
     * 
     * @param planId 巡检计划主键
     * @return 巡检计划
     */
    @Override
    public SbInspectionPlan selectSbInspectionPlanByPlanId(Long planId)
    {
        return sbInspectionPlanMapper.selectSbInspectionPlanByPlanId(planId);
    }

    /**
     * 查询巡检计划列表
     * 
     * @param sbInspectionPlan 巡检计划
     * @return 巡检计划
     */
    @Override
    public List<SbInspectionPlan> selectSbInspectionPlanList(SbInspectionPlan sbInspectionPlan)
    {
        return sbInspectionPlanMapper.selectSbInspectionPlanList(sbInspectionPlan);
    }

    /**
     * 查询巡检计划列表（包含关联信息）
     * 
     * @param sbInspectionPlan 巡检计划
     * @return 巡检计划集合
     */
    @Override
    public List<SbInspectionPlan> selectSbInspectionPlanWithInfoList(SbInspectionPlan sbInspectionPlan)
    {
        return sbInspectionPlanMapper.selectSbInspectionPlanWithInfoList(sbInspectionPlan);
    }

    /**
     * 新增巡检计划
     * 
     * @param sbInspectionPlan 巡检计划
     * @return 结果
     */
    @Override
    public int insertSbInspectionPlan(SbInspectionPlan sbInspectionPlan)
    {
        // 校验计划编号唯一性
        if (StringUtils.isNotEmpty(sbInspectionPlan.getPlanCode()) && 
            !checkPlanCodeUnique(sbInspectionPlan))
        {
            throw new ServiceException("新增巡检计划'" + sbInspectionPlan.getPlanName() + "'失败，计划编号已存在");
        }
        
        // 如果计划编号为空，自动生成
        if (StringUtils.isEmpty(sbInspectionPlan.getPlanCode()))
        {
            sbInspectionPlan.setPlanCode(generatePlanCode());
        }
        
        // 设置默认值
        sbInspectionPlan.setCreateTime(DateUtils.getNowDate());
        sbInspectionPlan.setCreateBy(SecurityUtils.getUsername());
        sbInspectionPlan.setIsDelete("0");
        
        // 设置更新信息，确保update_by字段有值
        sbInspectionPlan.setUpdateTime(DateUtils.getNowDate());
        sbInspectionPlan.setUpdateBy(SecurityUtils.getUsername());
        
        // 设置状态为默认启用
        if (sbInspectionPlan.getStatus() == null) {
            sbInspectionPlan.setStatus("1");
        }
        
        // 设置默认的自动生成巡检单标识
        if (sbInspectionPlan.getAutoGenerate() == null) {
            sbInspectionPlan.setAutoGenerate("1");
        }
        
        // 根据周期类型计算下一次巡检日期
        if (sbInspectionPlan.getStartDate() != null && sbInspectionPlan.getCycleType() != null) {
            Date nextDate = calculateNextInspectionDate(sbInspectionPlan.getStartDate(), 
                sbInspectionPlan.getCycleType(), sbInspectionPlan.getCycleValue());
            sbInspectionPlan.setNextInspectionDate(nextDate);
        }
        
        // 不再自动设置结束日期，完全由用户手动选择
        // 如果没有设置结束日期，可能会导致一些问题，所以记录日志
        if (sbInspectionPlan.getEndDate() == null) {
            logger.warn("巡检计划 '{}' 没有设置结束日期，这可能会导致巡检计划无限期执行", sbInspectionPlan.getPlanName());
        }
        
        // 处理type_id的外键约束问题 - 临时使用默认值
        // 设置一个存在的设备类型ID（这里假设ID为1的记录存在）
        // 实际使用时应该先查询一下确认有效的ID
        Long equipmentTypeId = sbEquipmentTypeMapper.selectFirstAvailableTypeId();
        if (equipmentTypeId == null) {
            throw new ServiceException("未找到可用的设备类型，请先添加设备类型。");
        }
        sbInspectionPlan.setTypeId(equipmentTypeId);
        
        return sbInspectionPlanMapper.insertSbInspectionPlan(sbInspectionPlan);
    }

    /**
     * 修改巡检计划
     * 
     * @param sbInspectionPlan 巡检计划
     * @return 结果
     */
    @Override
    public int updateSbInspectionPlan(SbInspectionPlan sbInspectionPlan)
    {
        sbInspectionPlan.setUpdateTime(DateUtils.getNowDate());
        sbInspectionPlan.setUpdateBy(SecurityUtils.getUsername());
        return sbInspectionPlanMapper.updateSbInspectionPlan(sbInspectionPlan);
    }

    /**
     * 批量删除巡检计划
     * 
     * @param planIds 需要删除的巡检计划主键
     * @return 结果
     */
    @Override
    public int deleteSbInspectionPlanByPlanIds(Long[] planIds)
    {
        return sbInspectionPlanMapper.deleteSbInspectionPlanByPlanIds(planIds);
    }

    /**
     * 删除巡检计划信息
     * 
     * @param planId 巡检计划主键
     * @return 结果
     */
    @Override
    public int deleteSbInspectionPlanByPlanId(Long planId)
    {
        return sbInspectionPlanMapper.deleteSbInspectionPlanByPlanId(planId);
    }

    /**
     * 校验计划编号是否唯一
     * 
     * @param sbInspectionPlan 巡检计划
     * @return 结果
     */
    @Override
    public boolean checkPlanCodeUnique(SbInspectionPlan sbInspectionPlan)
    {
        Long planId = StringUtils.isNull(sbInspectionPlan.getPlanId()) ? -1L : sbInspectionPlan.getPlanId();
        SbInspectionPlan info = sbInspectionPlanMapper.checkPlanCodeUnique(sbInspectionPlan.getPlanCode());
        if (StringUtils.isNotNull(info) && info.getPlanId().longValue() != planId.longValue())
        {
            return false;
        }
        return true;
    }

    /**
     * 生成巡检计划编号
     * 
     * @return 巡检计划编号
     */
    @Override
    public String generatePlanCode()
    {
        // 生成格式: PLAN-yyyyMMdd-序号
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dateStr = sdf.format(new Date());
        
        // 获取当天的计划数量作为序号
        int count = sbInspectionPlanMapper.countTodayInspectionPlans() + 1;
        
        String planCode = "PLAN-" + dateStr + "-" + String.format("%03d", count);
        
        // 检查生成的编号是否已存在，如果存在则增加序号直到找到唯一的编号
        while (!checkPlanCodeUnique(new SbInspectionPlan(planCode))) {
            count++;
            planCode = "PLAN-" + dateStr + "-" + String.format("%03d", count);
        }
        
        return planCode;
    }

    /**
     * 根据设备ID查询巡检计划
     * 
     * @param equipmentId 设备ID
     * @return 巡检计划列表
     */
    @Override
    public List<SbInspectionPlan> selectSbInspectionPlanByEquipmentId(Long equipmentId)
    {
        return sbInspectionPlanMapper.selectSbInspectionPlanByEquipmentId(equipmentId);
    }

    /**
     * 根据巡检人员ID查询巡检计划
     * 
     * @param inspectorId 巡检人员ID
     * @return 巡检计划列表
     */
    @Override
    public List<SbInspectionPlan> selectSbInspectionPlanByInspectorId(Long inspectorId)
    {
        return sbInspectionPlanMapper.selectSbInspectionPlanByInspectorId(inspectorId);
    }

    /**
     * 根据配置ID查询巡检计划
     * 
     * @param configId 配置ID
     * @return 巡检计划列表
     */
    @Override
    public List<SbInspectionPlan> selectSbInspectionPlanByConfigId(Long configId)
    {
        return sbInspectionPlanMapper.selectSbInspectionPlanByConfigId(configId);
                }

    /**
     * 根据巡检计划创建巡检单
     *
     * @param plan 巡检计划
     * @return 巡检单
     */
    @Override
    @Transactional
    public SbInspectionRecord createInspectionRecordFromPlan(SbInspectionPlan plan)
    {
        logger.info("根据计划创建巡检单: planId={}, planName={}", plan.getPlanId(), plan.getPlanName());
        
        try {
        // 创建巡检记录
        SbInspectionRecord record = new SbInspectionRecord();
        
        // 设置基本信息
        record.setPlanId(plan.getPlanId());
        record.setPlanName(plan.getPlanName());
        
        // 设置配置信息
        record.setConfigId(plan.getConfigId());
        logger.info("设置巡检记录配置信息: planId={}, configId={}, planName={}", 
            plan.getPlanId(), plan.getConfigId(), plan.getPlanName());
        
        // 设置设备信息
        record.setEquipmentId(plan.getEquipmentId());
        record.setEquipmentName(plan.getEquipmentName());
        
        // 设置巡检人员
        record.setInspectorId(plan.getInspectorId());
        record.setInspectorName(plan.getInspectorName());
            
            // 设置部门信息
            record.setDeptId(plan.getDeptId());
            record.setDeptName(plan.getDeptName());
        
        // 设置巡检时间信息
        Date now = DateUtils.getNowDate();
        record.setInspectionDate(now);
        
        // 生成巡检单编号
        record.setRecordCode(generateRecordCodeFromPlan(plan));
        
        // 设置初始状态为待巡检
        record.setStatus("0");
        record.setIsDelete("0");
        
        // 设置创建者信息
        record.setCreateBy(SecurityUtils.getUsername());
        record.setCreateTime(now);
            
            // 同时设置updateBy和updateTime
            record.setUpdateBy(SecurityUtils.getUsername());
            record.setUpdateTime(now);
        
        // 保存巡检单
            int rows = sbInspectionRecordService.insertSbInspectionRecord(record);
            if (rows <= 0) {
                logger.error("保存巡检单失败");
                throw new ServiceException("保存巡检单失败");
            }
        
        // 更新计划的下次巡检日期
        updateNextInspectionDate(plan);
            
            logger.info("巡检单创建成功: recordId={}, recordCode={}", record.getRecordId(), record.getRecordCode());
        
        // 返回创建的巡检单
        return record;
        } catch (Exception e) {
            logger.error("创建巡检单异常", e);
            throw new ServiceException("创建巡检单失败: " + e.getMessage());
        }
    }

    /**
     * 生成巡检单编号
     * 
     * @param plan 巡检计划
     * @return 巡检单编号
     */
    private String generateRecordCodeFromPlan(SbInspectionPlan plan) {
        // 生成格式: XJ-设备ID缩写-yyyyMMdd-序号
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dateStr = sdf.format(new Date());
        
        String equipPrefix = "EQ";
        if (plan.getEquipmentId() != null) {
            equipPrefix = "EQ" + plan.getEquipmentId().toString().substring(0, Math.min(4, plan.getEquipmentId().toString().length()));
        }
        
        // 获取当天的巡检单数量作为序号
        int count = sbInspectionRecordService.countTodayInspectionRecords() + 1;
        
        return "XJ-" + equipPrefix + "-" + dateStr + "-" + String.format("%03d", count);
    }

    /**
     * 更新计划的下次巡检日期
     * 
     * @param plan 巡检计划
     */
    private void updateNextInspectionDate(SbInspectionPlan plan) {
        // 根据周期类型计算下次巡检日期
        String cycleType = plan.getCycleType();
        Date nextDate = null;
        
        if ("1".equals(cycleType)) {
            // 每天
            nextDate = DateUtils.addDays(new Date(), 1);
        } else if ("2".equals(cycleType)) {
            // 每周
            nextDate = DateUtils.addDays(new Date(), 7);
        } else if ("3".equals(cycleType)) {
            // 每月
            nextDate = DateUtils.addMonths(new Date(), 1);
        } else if ("4".equals(cycleType)) {
            // 每季度
            nextDate = DateUtils.addMonths(new Date(), 3);
        } else if ("5".equals(cycleType)) {
            // 每年
            nextDate = DateUtils.addYears(new Date(), 1);
        }
        
        if (nextDate != null) {
            // 如果超过计划结束日期，则不再设置下次巡检日期
            if (plan.getEndDate() != null && nextDate.after(plan.getEndDate())) {
                // 计划已结束，不再设置下次巡检日期
                logger.info("计划已结束，不再设置下次巡检日期: planId={}", plan.getPlanId());
                return;
            }
            
            // 更新计划的下次巡检日期
            SbInspectionPlan updatePlan = new SbInspectionPlan();
            updatePlan.setPlanId(plan.getPlanId());
            updatePlan.setNextInspectionDate(nextDate);
            updatePlan.setUpdateBy(SecurityUtils.getUsername());
            updatePlan.setUpdateTime(DateUtils.getNowDate());
            
            sbInspectionPlanMapper.updateSbInspectionPlan(updatePlan);
            logger.info("更新计划下次巡检日期: planId={}, nextDate={}", plan.getPlanId(), nextDate);
        }
    }

    /**
     * 计算下一次巡检日期
     *
     * @param startDate 起始日期
     * @param cycleType 周期类型（1每天 2每周 3每月 4每季度 5每年）
     * @param cycleValue 周期值
     * @return 下一次巡检日期
     */
    private Date calculateNextInspectionDate(Date startDate, String cycleType, Integer cycleValue) {
        if (startDate == null || cycleType == null) {
            return null;
        }
        
        // 如果周期值为空，默认为1
        int value = cycleValue != null ? cycleValue : 1;
        
        // 创建日历实例
        java.util.Calendar calendar = java.util.Calendar.getInstance();
        calendar.setTime(startDate);
        
        switch (cycleType) {
            case "1": // 每天
                calendar.add(java.util.Calendar.DAY_OF_MONTH, value);
                break;
            case "2": // 每周
                calendar.add(java.util.Calendar.WEEK_OF_YEAR, value);
                break;
            case "3": // 每月
                calendar.add(java.util.Calendar.MONTH, value);
                break;
            case "4": // 每季度
                calendar.add(java.util.Calendar.MONTH, value * 3);
                break;
            case "5": // 每年
                calendar.add(java.util.Calendar.YEAR, value);
                break;
            default:
                return startDate;
        }
        
        return calendar.getTime();
    }
} 